In older games, which have 2D graphics, one
can run into the next situation. The hero jumps along the platforms or islands
that hang in the air. He must move himself from one side of the screen to the
other. The hero can jump from any platform number i to any platform number k,
spending (i – k)2 * (yi – yk)2 energy,
where yi and
yk
are the heights where these platforms hang. Obviously energy should be spent
frugally.
You are given the heights of the platforms
in order from the left side to the right. Can you find the minimum amount of
energy to get from the 1-st (start) platform to the n-th (last)?
Input. The first line contains the number of
platforms n (1 ≤ n ≤ 4000). The second line gives n integers – the heights of the platforms, which
absolute values are not greater than 200000.
Output. Print the singe integer which is the
minimum amount of energy to get from the 1-st platform to the n-th.
Sample
input |
Sample
output |
4 1 2 3 30 |
731 |
graphs – Dijkstra
algorithm
Consider each
platform as a vertex of the graph. Between each pair of vertices i and j make an undirected edge g[i][j] with weight (i – j)2 * (yi – yj)2 (the amount of energy required to move between
vertices i and j). Now you must find the minimum path between
the first and the last vertices, that can be done using Dijkstra’s algorithm.
There is no need
to keep the graph in memory, since all values of g[i][j] can be calculated using
the above formula.
Example
Graph and its weight
matrix are given below:
The hero should
move along the platforms in the order 1 → 2 → 3 → 4, spending for it 1 + 1 + 729 =
731 energy units.
Declare the constants:
·
MAX – the number of platforms;
·
INF – thr maximum number of type kong long;
#define MAX 4001
#define INF
0x3F3F3F3F3F3F3F3FLL
Declare the arrays:
int used[MAX];
long long m[MAX], dist[MAX];
Read the input data – the platform heights. Platforms are numbered from 0 to n – 1.
scanf("%d", &n);
for (i = 0; i < n; i++)
scanf("%lld",
&m[i]);
Initialize the array of shortest distances dist.
memset(dist, 0x3F, sizeof(dist));
dist[0] =
0;
Run the Dijkstra’s algorithm from the vertex 0.
for (i = 1; i < n; i++)
{
min =
INF; w = -1;
for (j =
0; j < n; j++)
if
(!used[j] && dist[j] < min) { min = dist[j]; w = j; }
if (w
< 0) break;
for (j =
0; j < n; j++)
{
Compue the distance len between the vertices w and j.
long long len = (w - j) * (w - j) * (m[j] - m[w])
* (m[j] - m[w]);
If the shortest distance to the vertex j has not yet
been calculated, then relax the edge (w, j).
if
(!used[j] && dist[j] > dist[w]
+ len) dist[j] = dist[w] +
len;
}
used[w]
= 1;
}
Print the shortest distance to the vertex n – 1.
printf("%lld\n", dist[n - 1]);
printf("%lld\n", dist[n - 1]);
import java.util.*;
public class Main
{
static int used[];
static long m[], dist[];
static long INF = 1000000000000000000L;
public static void main(String[] args)
{
Scanner con = new
Scanner(System.in);
int n = con.nextInt();
m = new long[n];
for (int i = 0; i < n; i++)
m[i] = con.nextLong();
used = new int[n];
dist = new long[n];
Arrays.fill(dist, INF);
dist[0] = 0;
for (int i = 1; i < n; i++)
{
long min = INF;
int w = -1;
for (int j = 0; j < n; j++)
if (used[j] == 0 && dist[j] < min) { min = dist[j]; w = j; }
if (w < 0) break;
for (int j = 0; j < n; j++)
{
long len = (w - j) * (w - j) * (m[j] - m[w]) * (m[j] - m[w]);
if (used[j] == 0 && dist[j] > dist[w] + len)
dist[j] = dist[w] + len;
}
used[w] = 1;
}
System.out.println(dist[n-1]);
con.close();
}
}